import com.speljohan.rsbot.bot.Bot;
import com.speljohan.rsbot.event.events.ServerMessageEvent;
import com.speljohan.rsbot.event.listeners.ServerMessageListener;
import com.speljohan.rsbot.script.Random;
import com.speljohan.rsbot.script.wrappers.RSInterface;
import com.speljohan.rsbot.script.wrappers.RSInterfaceChild;
import com.speljohan.rsbot.script.wrappers.RSNPC;
import com.speljohan.rsbot.script.wrappers.RSObject;
import com.speljohan.rsbot.script.wrappers.RSTile;

/**
 * Solves the Evil Twin Random.
 * 
 * @version 1.0 - 1/03/09
 * @author Xhamolk
 */
public class EvilTwin extends Random {

	/*
	 * * Author Notes: To fix this Anti-Random, make sure you check this
	 * methods: method - moveClay( RSTile ) boolean - clawOn ( RSTile ) boolean
	 * - withMolly ( ) State - getState ( )
	 */

	private enum State {
		AtMolly, CatchTwin, Done, Finalize;
	}

	boolean bitchCaught = false;
	RSObject claw;

	int clawID = 14976;
	int closeButton = 33;
	int controlID = 14978;

	int controlsIface = 240;
	RSObject door;
	int doorID = 14982;

	RSNPC molly;
	int mollyID;
	private final ServerMessageListener serverListener = new ServerMessageListener() {

		@Override
		public void serverMessageRecieved(final ServerMessageEvent e) {
			final String message = e.getMessage().toLowerCase();
			if (message.contains("ratulations! you caught the evil")) {
				bitchCaught = true;
			}
		}

	};
	int submitButton = 23;
	boolean talked = false;

	int twinID;

	public EvilTwin() {
		setParameter("name", "Evil Twin");
		setParameter("author", "Xhamolk");
		setParameter("version", 1.0);
	}

	@Override
	public boolean activateCondition() {
		// log.info("Testing molly");
		if (!isLoggedIn()) {
			return false;
		}

		claw = claw();
		if (claw != null) {
			// log.info(" Claw Found ");
			molly = molly();
			if (molly != null) {
				// log.info(" Molly Found ");
				mollyID = molly.getID();
				twinID = mollyID - 40; // Thankz to Illusion
				log.info("Molly ID: " + mollyID);
				log.info("Expected Twin ID: " + twinID);
				return true;
			}
		}
		return false;
	}

	private RSObject claw() {
		return findObject(50, clawID);
	}

	private boolean clawOn(final RSTile location) {

		return claw.getLocation().equals(location);

	}

	private State getState() {
		if ((molly = molly()) == null && (claw = claw()) == null) {
			return State.Done;
		}

		if (bitchCaught) {
			return State.Finalize;
		}

		if (withMolly()) {
			return State.AtMolly;
		}

		return State.CatchTwin;
	}

	@Override
	public int loop() {
		if (canContinue()) {
			clickContinue();
			return random(800, 1000);
		}
		if (getMyPlayer().isMoving()) {
			return random(800, 1000);
		}
		switch (getState()) {
		case AtMolly:
			final RSInterfaceChild talkIface = getChildInterface(228, 3);
			if (talkIface.isValid()) {
				atInterface(talkIface);
				break;
			}
			door = findObject(doorID);
			if (door != null) {
				atDoor(door, "east", "Open Door");
			}
			break;

		case CatchTwin:

			final RSInterface cIface = RSInterface.getInterface(controlsIface);
			if (cIface.isValid()) {
				final RSNPC twin = getNearestNPCByID(twinID);
				if (!clawOn(twin.getLocation())) {
					moveCLayTo(twin.getLocation());
					break;
				}
				atInterface(cIface.getChild(submitButton));
				break;
			}

			final RSObject controller = findObject(50, controlID);
			if (controller != null) {
				atObject(controller, "Use");
			}
			break;

		case Done:
			Bot.getEventManager().removeListener(serverListener);
			return -1;

		case Finalize:
			if (distanceTo(molly) > 5) {
				door = findObject(doorID);
				atDoor(door, "east", "Open Door");
				break;
			}
			break;
		}
		return random(400, 800);
	}

	private RSNPC molly() {
		return getNearestNPCByName("Molly");
	}

	private void moveCLayTo(final RSTile tLoc) {

		final RSTile cLoc = claw.getLocation();
		final RSInterface cIface = getInterface(controlsIface);

		final int tLocX = tLoc.getX();
		final int tLocY = tLoc.getY();

		final int cLocX = cLoc.getX();
		final int cLocY = cLoc.getY();

		if (tLocX < cLocX) {
			// If Twin.X < Claw.X: move to Left
			atInterface(cIface.getChild(16));
			return;
		}

		if (tLocX > cLocX) {
			// If Twin.X > Claw.X: move to right
			atInterface(cIface.getChild(21));
			return;
		}

		if (tLocY < cLocY) {
			// If Twin.Y < Claw.Y: move up
			atInterface(cIface.getChild(6));
			return;
		}

		if (tLocX > cLocX) {
			// If Twin.Y > Claw.Y: move down
			atInterface(cIface.getChild(11));
			return;
		}

	}

	private boolean withMolly() {
		final RSTile mTile = molly.getLocation();

		final int minX = mTile.getX() - 2;
		final int maxX = mTile.getX() + 5;

		final int minY = mTile.getY() - 2;
		final int maxY = mTile.getY() + 5;

		final int myX = getMyPlayer().getLocation().getX();
		final int myY = getMyPlayer().getLocation().getY();

		if (minX < myX && myX > maxX) {
			if (minY < myY && myY > maxY) {
				return true;
			}
		}

		return false;
	}

}